﻿#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lame/lame.h"

// 定义常量
#define PCM_FILE "test.wav"
#define MP3_FILE "output.mp3"
#define BIT_RATE 128 // 例如设置比特率为128kbps
#define SAMPLE_RATE 44100
#define BYTES_PER_SAMPLE 2 // 16位样本

#define AUIDO_INPUT_BUFFER_SIZE 4096 // 假设你的 PCM 数据块大小是 4096 字节 
#define AUIDO_CHANNELS 1  

/// <summary>
/// PCM转Mp3文件
/// </summary>
/// <param name="wavFilePath">wav文件路径</param>
/// <param name="mp3FilePath">mp3文件路径</param>
/// <param name="headLen">头长</param>
/// <returns></returns>
int WaveToMp3(const char* wavFilePath, const char* mp3FilePath,
    int inSamplerate, int outSamplerate, int channels, int brate, MPEG_mode mode, int quality)
{
    if (wavFilePath == nullptr || strlen(wavFilePath) <= 3)
    {
        return -1;
    }

    if (mp3FilePath == nullptr || strlen(mp3FilePath) <= 5)
    {
        return -1;
    }

    FILE* wavFile = fopen(wavFilePath, "rb");
    if (!wavFile)
    {
        perror("Error opening WAV file");
        return -1;
    }

    fseek(wavFile, 44L, 0); //把stream指针移动到离文件开头44字节处；
    FILE* mp3File = fopen(mp3FilePath, "wb");

    if (!mp3File)
    {
        perror("Error opening mp3 file");
        return -1;
    }

    // 初始化LAME编码器
    lame_t lame = lame_init();
    if (lame == nullptr) { return -1; }

    int ret = 0;
    do
    {
        // 设置编码参数  
        lame_set_num_channels(lame, channels);
        lame_set_in_samplerate(lame, inSamplerate);
        lame_set_out_samplerate(lame, outSamplerate); // 通常输出采样率与输入采样率相同  
        lame_set_brate(lame, 128);
        lame_set_quality(lame, quality); // 质量设置，范围从 0（最高）到 9（最低）  
        lame_set_VBR(lame, vbr_default);
        lame_set_mode(lame, MONO); // 立体声模式 

        int ret_code = lame_init_params(lame);

        if (ret_code < 0)
        {
            printf("lame_init error:%d", ret_code);
            ret = -2;
            break;
        }

        int pcmBufferSize = AUIDO_INPUT_BUFFER_SIZE / (channels * sizeof(short int));
        short int pcmBuffer[pcmBufferSize];
        memset(pcmBuffer, 0, sizeof(pcmBuffer));

        int mp3BufferSize = lame_get_framesize(lame);
        unsigned char mp3Buffer[mp3BufferSize];
        memset(mp3Buffer, 0, sizeof(mp3Buffer));

        int readBytes = -1, encodedBytes = -1, encodedBytesCount = 0;
        do
        {
            readBytes = fread(pcmBuffer, sizeof(int8_t), sizeof(pcmBuffer) / sizeof(short int), wavFile);

            if (readBytes <= 0)
            {
                lame_encode_flush(lame, mp3Buffer, mp3BufferSize);
                break;
            }

            if (1 == channels)
            {
                encodedBytes = lame_encode_buffer(lame, pcmBuffer, NULL, readBytes / (AUIDO_CHANNELS * sizeof(short int)), mp3Buffer, mp3BufferSize); // 单声道音频转码
            }
            else
            {
                encodedBytes = lame_encode_buffer_interleaved(lame, pcmBuffer, readBytes / (AUIDO_CHANNELS * sizeof(short int)), mp3Buffer, mp3BufferSize); // 多声道音频转码
            }

            if (encodedBytes < 0)
            {
                fprintf(stderr, "Encoding error\n");
                ret = -3;
                break;
            }

            fwrite(mp3Buffer, 1, encodedBytes, mp3File);
            encodedBytesCount += encodedBytes;

            memset(pcmBuffer, 0, sizeof(pcmBuffer));
            memset(mp3Buffer, 0, sizeof(mp3Buffer));

        } while (readBytes > 0);

        if (encodedBytesCount <= 0) { ret = -4; break; }
        ret = 0;

    } while (0);

    if (lame) { lame_close(lame); }
    if (wavFile) { fclose(wavFile); }
    if (mp3File) { fclose(mp3File); }

    return ret;
}


int main()
{
    WaveToMp3("test.wav", "output.mp3", 44100, 44100, 1, 128, MONO, 0);

    printf("Conversion from WAV to MP3 completed successfully.\n");
    return 0;
}